#include "board_config.h"
#include "gpio.h"

 GPIO_TypeDef* get_gpio_port(uint32_t io) {
	u16 io_port = PORT(io);
    switch (io_port) {
        case 0: return GPIOA;
        case 1: return GPIOB;
        case 2: return GPIOC;
        case 3: return GPIOD;
        case 4: return GPIOE;
        case 5: return GPIOF;
#ifdef STM32F4
        case 6: return GPIOG;
#endif        
        default: return (GPIO_TypeDef*)0; // impossible
    }
}

void _gpio_init(u32 io, uint32_t mode, uint32_t pull, uint32_t speed, uint32_t alt) {
  	GPIO_InitTypeDef   GPIO_InitStructure;
  	GPIO_TypeDef *port = get_gpio_port(io);
	if (port == NULL) {
		return;
	}
    if (port == GPIOA) {
        __HAL_RCC_GPIOA_CLK_ENABLE();
    } else if (port == GPIOB) {
        __HAL_RCC_GPIOB_CLK_ENABLE();
    } else if (port == GPIOC) {
        __HAL_RCC_GPIOC_CLK_ENABLE();
    } else if (port == GPIOD) {
        __HAL_RCC_GPIOD_CLK_ENABLE();
    } else if (port == GPIOE) {
        __HAL_RCC_GPIOE_CLK_ENABLE();
    } else if (port == GPIOF) {
        __HAL_RCC_GPIOF_CLK_ENABLE();
    } else if (port == GPIOG) {
        __HAL_RCC_GPIOG_CLK_ENABLE();
    }
#ifdef STM32F4    
    else if (port == GPIOH) {
        __HAL_RCC_GPIOH_CLK_ENABLE();
    }
#endif
    else {
        return;
    }
  	GPIO_InitStructure.Mode = mode;
  	GPIO_InitStructure.Pull = pull;
	GPIO_InitStructure.Speed = speed;
    GPIO_InitStructure.Alternate = alt;
  	GPIO_InitStructure.Pin = PIN(io);
  	HAL_GPIO_Init(port, &GPIO_InitStructure);
}


void gpio2_init(u32 io, uint32_t mode, uint32_t pull, uint32_t speed) {
    _gpio_init(io, mode, pull, speed, 0);
}

void gpio2_analog_init(u32 io) {
    gpio2_init(io, GPIO_MODE_ANALOG, GPIO_NOPULL, 0);
}


void gpio2_af_init(u32 io, u32 mode, u32 pull, u32 speed, u32 alt) {
    _gpio_init(io, mode, pull, speed, alt);
}

void gpio2_deinit(uint32_t io) {
  	GPIO_TypeDef *port = get_gpio_port(io);
	if (port == NULL) {
		return;
	}
  	HAL_GPIO_DeInit(port, PIN(io));
}

void gpio2_write(u32 io, bool set) {
	HAL_GPIO_WritePin(get_gpio_port(io), PIN(io), set ? GPIO_PIN_SET : GPIO_PIN_RESET);
}

bool gpio2_read(u32 io) {
	GPIO_TypeDef * port = get_gpio_port(io);
	return port && (port->IDR & PIN(io));
}
